﻿//------------------------------------------------------------------------------
// <copyright company="Microsoft Corporation">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using DataConnectionDialog = Microsoft.Data.ConnectionUI.DataConnectionDialog;
using DataProvider = Microsoft.Data.ConnectionUI.DataProvider;
using DataSource = Microsoft.Data.ConnectionUI.DataSource;

namespace Grasp.DbEntityGenerator.Utils
{
    /// <summary>
    ///     Provide a default implementation for the storage of DataConnection Dialog UI configuration.
    /// </summary>
    public class DataConnectionConfiguration : IDataConnectionConfiguration
    {
        private const string ConfigFileName = @"DataConnection.xml";
        private readonly string _fullFilePath;
        private readonly XDocument _xDoc;

        // Available data sources:

        // Available data providers: 
        private IDictionary<string, DataProvider> _dataProviders;
        private IDictionary<string, DataSource> _dataSources;

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="path">Configuration file path.</param>
        public DataConnectionConfiguration(string path)
        {
            _fullFilePath = !String.IsNullOrEmpty(path)
                ? Path.GetFullPath(Path.Combine(path, ConfigFileName))
                : Path.Combine(Environment.CurrentDirectory, ConfigFileName);
            if (!String.IsNullOrEmpty(_fullFilePath) && File.Exists(_fullFilePath))
            {
                _xDoc = XDocument.Load(_fullFilePath);
            }
            else
            {
                _xDoc = new XDocument();
                _xDoc.Add(new XElement("ConnectionDialog", new XElement("DataSourceSelection")));
            }

            RootElement = _xDoc.Root;
        }

        public XElement RootElement { get; set; }

        public string GetSelectedSource()
        {
            try
            {
                XElement xElem = RootElement.Element("DataSourceSelection");
                if (xElem != null)
                {
                    XElement sourceElem = xElem.Element("SelectedSource");
                    if (sourceElem != null)
                    {
                        return sourceElem.Value;
                    }
                }
            }
            catch
            {
                return null;
            }
            return null;
        }

        public string GetSelectedProvider()
        {
            try
            {
                XElement xElem = RootElement.Element("DataSourceSelection");
                if (xElem != null)
                {
                    XElement providerElem = xElem.Element("SelectedProvider");
                    if (providerElem != null)
                    {
                        return providerElem.Value;
                    }
                }
            }
            catch
            {
                return null;
            }
            return null;
        }

        public void SaveSelectedSource(string source)
        {
            if (!String.IsNullOrEmpty(source))
            {
                try
                {
                    XElement xElem = RootElement.Element("DataSourceSelection");
                    if (xElem != null)
                    {
                        XElement sourceElem = xElem.Element("SelectedSource");
                        if (sourceElem != null)
                        {
                            sourceElem.Value = source;
                        }
                        else
                        {
                            xElem.Add(new XElement("SelectedSource", source));
                        }
                    }
                }
                catch
                {
                }
            }
        }

        public void SaveSelectedProvider(string provider)
        {
            if (!String.IsNullOrEmpty(provider))
            {
                try
                {
                    XElement xElem = RootElement.Element("DataSourceSelection");
                    if (xElem != null)
                    {
                        XElement sourceElem = xElem.Element("SelectedProvider");
                        if (sourceElem != null)
                        {
                            sourceElem.Value = provider;
                        }
                        else
                        {
                            xElem.Add(new XElement("SelectedProvider", provider));
                        }
                    }
                }
                catch
                {
                }
            }
        }

        public void LoadConfiguration(DataConnectionDialog dialog)
        {
            dialog.DataSources.Add(DataSource.SqlDataSource);
            dialog.DataSources.Add(DataSource.SqlFileDataSource);
            dialog.DataSources.Add(DataSource.OracleDataSource);
            dialog.DataSources.Add(DataSource.AccessDataSource);
            dialog.DataSources.Add(DataSource.OdbcDataSource);
            dialog.DataSources.Add(Microsoft.Data.ConnectionUI.MySql.MySql.MySqlDataSource);

            dialog.UnspecifiedDataSource.Providers.Add(DataProvider.SqlDataProvider);
            dialog.UnspecifiedDataSource.Providers.Add(DataProvider.OracleDataProvider);
            dialog.UnspecifiedDataSource.Providers.Add(DataProvider.OleDBDataProvider);
            dialog.UnspecifiedDataSource.Providers.Add(DataProvider.OdbcDataProvider);
            dialog.DataSources.Add(dialog.UnspecifiedDataSource);

            _dataSources = new Dictionary<string, DataSource>
            {
                {DataSource.SqlDataSource.Name, DataSource.SqlDataSource},
                {DataSource.SqlFileDataSource.Name, DataSource.SqlFileDataSource},
                {DataSource.OracleDataSource.Name, DataSource.OracleDataSource},
                {DataSource.AccessDataSource.Name, DataSource.AccessDataSource},
                {DataSource.OdbcDataSource.Name, DataSource.OdbcDataSource},
                {Microsoft.Data.ConnectionUI.MySql.MySql.MySqlDataSource.Name, Microsoft.Data.ConnectionUI.MySql.MySql.MySqlDataSource},
                {dialog.UnspecifiedDataSource.DisplayName, dialog.UnspecifiedDataSource}
            };

            _dataProviders = new Dictionary<string, DataProvider>
            {
                {DataProvider.SqlDataProvider.Name, DataProvider.SqlDataProvider},
                {DataProvider.OracleDataProvider.Name, DataProvider.OracleDataProvider},
                {DataProvider.OleDBDataProvider.Name, DataProvider.OleDBDataProvider},
                {DataProvider.OdbcDataProvider.Name, DataProvider.OdbcDataProvider},
                {Microsoft.Data.ConnectionUI.MySql.MySql.MySqlDataProvider.Name, Microsoft.Data.ConnectionUI.MySql.MySql.MySqlDataProvider}
            };

            DataSource ds = null;
            string dsName = GetSelectedSource();
            if (!String.IsNullOrEmpty(dsName) && _dataSources.TryGetValue(dsName, out ds))
            {
                dialog.SelectedDataSource = ds;
            }

            DataProvider dp = null;
            string dpName = GetSelectedProvider();
            if (!String.IsNullOrEmpty(dpName) && _dataProviders.TryGetValue(dpName, out dp))
            {
                dialog.SelectedDataProvider = dp;
            }
        }

        public void SaveConfiguration(DataConnectionDialog dcd)
        {
            if (dcd.SaveSelection)
            {
                DataSource ds = dcd.SelectedDataSource;
                if (ds != null)
                {
                    SaveSelectedSource(ds == dcd.UnspecifiedDataSource ? ds.DisplayName : ds.Name);
                }
                DataProvider dp = dcd.SelectedDataProvider;
                if (dp != null)
                {
                    SaveSelectedProvider(dp.Name);
                }

                _xDoc.Save(_fullFilePath);
            }
        }
    }
}